Adds a bunch of new APIs to render textures with theming.
FIXME: Cannot draw shadows for textures.
}
}
-GskRenderNode *
-gtk_icon_helper_get_render_node (GtkIconHelper *self,
- GskRenderer *renderer)
+void
+gtk_icon_helper_snapshot (GtkIconHelper *self,
+ GtkSnapshot *snapshot)
{
GskTexture *texture;
GskRenderNode *node;
graphene_rect_t bounds;
- gtk_icon_helper_ensure_texture (self, renderer);
+ gtk_icon_helper_ensure_texture (self, gtk_snapshot_get_renderer (snapshot));
texture = self->priv->texture;
if (texture == NULL)
- return NULL;
+ return;
graphene_rect_init (&bounds, 0, 0, gsk_texture_get_width (texture), gsk_texture_get_height (texture));
- node = gsk_renderer_create_render_node (renderer);
- gsk_render_node_set_name (node, "Icon Helper");
- gsk_render_node_set_bounds (node, &bounds);
+ node = gtk_snapshot_append (snapshot, &bounds, "Icon Helper");
gsk_render_node_set_texture (node, texture);
-
- return node;
+ gsk_render_node_unref (node);
}
gboolean
cairo_t *cr,
gdouble x,
gdouble y);
-GskRenderNode * gtk_icon_helper_get_render_node (GtkIconHelper *self,
- GskRenderer *renderer);
+void gtk_icon_helper_snapshot (GtkIconHelper *self,
+ GtkSnapshot *snapshot);
gboolean _gtk_icon_helper_get_force_scale_pixbuf (GtkIconHelper *self);
void _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self,
#define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
-static GskRenderNode *gtk_image_get_render_node (GtkWidget *widget,
- GskRenderer *renderer);
+static void gtk_image_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot);
static void gtk_image_size_allocate (GtkWidget *widget,
GtkAllocation*allocation);
static void gtk_image_unmap (GtkWidget *widget);
gint *minimum_baseline,
gint *natural_baseline,
gpointer unused);
+static gboolean gtk_image_render_contents (GtkCssGadget *gadget,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ int width,
+ int height,
+ gpointer data);
static void gtk_image_style_updated (GtkWidget *widget);
static void gtk_image_finalize (GObject *object);
gobject_class->finalize = gtk_image_finalize;
widget_class = GTK_WIDGET_CLASS (class);
- widget_class->get_render_node = gtk_image_get_render_node;
+ widget_class->snapshot = gtk_image_snapshot;
widget_class->measure = gtk_image_measure;
widget_class->size_allocate = gtk_image_size_allocate;
widget_class->unmap = gtk_image_unmap;
gtk_image_get_content_size,
NULL,
NULL,
- NULL,
+ gtk_image_render_contents,
NULL, NULL);
+
}
static void
}
-static GskRenderNode *
-gtk_image_get_render_node (GtkWidget *widget,
- GskRenderer *renderer)
+static void
+gtk_image_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
- GtkImage *image = GTK_IMAGE (widget);
- GtkImagePrivate *priv = image->priv;
- gint w, h, baseline;
- gint x, y, width, height;
- GskRenderNode *res;
- GskRenderNode *node;
- GtkAllocation alloc, clip;
- cairo_t *cr;
-
- res = gtk_css_gadget_get_render_node (priv->gadget, renderer, FALSE);
-
- if (res == NULL)
- return NULL;
-
- if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
- {
- node = gtk_widget_create_render_node (widget, renderer, "Image Content");
+ gtk_css_gadget_snapshot (GTK_IMAGE (widget)->priv->gadget,
+ snapshot);
+}
- gtk_widget_get_clip (widget, &clip);
- _gtk_widget_get_allocation (widget, &alloc);
+static gboolean
+gtk_image_render_contents (GtkCssGadget *gadget,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ int width,
+ int height,
+ gpointer data)
+{
+ GtkWidget *widget;
+ GtkImage *image;
+ GtkImagePrivate *priv;
+ gint w, h, baseline;
- cr = gsk_render_node_get_draw_context (node, renderer);
- cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y);
- x = 0;
- y = 0;
- width = alloc.width;
- height = alloc.height;
+ widget = gtk_css_gadget_get_owner (gadget);
+ image = GTK_IMAGE (widget);
+ priv = image->priv;
- _gtk_icon_helper_get_size (priv->icon_helper, &w, &h);
+ _gtk_icon_helper_get_size (priv->icon_helper, &w, &h);
- baseline = gtk_widget_get_allocated_baseline (widget);
+ baseline = gtk_widget_get_allocated_baseline (widget);
- if (baseline == -1)
- y += floor(height - h) / 2;
- else
- y += CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
+ if (baseline == -1)
+ y += floor(height - h) / 2;
+ else
+ y += CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
- x += (width - w) / 2;
+ x += (width - w) / 2;
+ gtk_snapshot_translate_2d (snapshot, x, y);
+ if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
+ {
GtkStyleContext *context = gtk_widget_get_style_context (widget);
GdkPixbuf *pixbuf = get_animation_frame (image);
- gtk_render_icon (context, cr, pixbuf, x, y);
+ gtk_snapshot_render_icon (snapshot, context, pixbuf, x, y);
+
g_object_unref (pixbuf);
-
- cairo_destroy (cr);
}
else
{
- node = gtk_icon_helper_get_render_node (priv->icon_helper, renderer);
- }
-
- if (node != NULL)
- {
- gsk_render_node_append_child (res, node);
- gsk_render_node_unref (node);
+ gtk_icon_helper_snapshot (priv->icon_helper, snapshot);
}
+ gtk_snapshot_translate_2d (snapshot, -x, -y);
- return res;
+ return FALSE;
}
static void
#include "gtkcssshadowsvalueprivate.h"
#include "gtkcssstyleprivate.h"
#include "gtkcsstransformvalueprivate.h"
+#include "gtksnapshotprivate.h"
#include <math.h>
extents->height += border.top + border.bottom;
}
+void
+gtk_css_style_snapshot_icon (GtkCssStyle *style,
+ GtkSnapshot *snapshot,
+ GskTexture *texture)
+{
+ const GtkCssValue *shadows, *transform;
+ cairo_matrix_t transform_matrix;
+ graphene_matrix_t matrix, other, saved_matrix;
+ graphene_rect_t bounds;
+ GskRenderNode *node;
+ int width, height;
+
+ g_return_if_fail (GTK_IS_CSS_STYLE (style));
+ g_return_if_fail (snapshot != NULL);
+ g_return_if_fail (GSK_IS_TEXTURE (texture));
+
+ shadows = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW);
+ transform = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM);
+ width = gsk_texture_get_width (texture);
+ height = gsk_texture_get_height (texture);
+
+ if (!_gtk_css_transform_value_get_matrix (transform, &transform_matrix))
+ return;
+
+ graphene_matrix_init_from_matrix (&saved_matrix, gtk_snapshot_get_transform (snapshot));
+
+ /* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
+ graphene_matrix_init_translate (&matrix, &(graphene_point3d_t)GRAPHENE_POINT3D_INIT(width / 2.0, height / 2.0, 0));
+ graphene_matrix_init_from_2d (&other, transform_matrix.xx, transform_matrix.yx,
+ transform_matrix.xy, transform_matrix.yy,
+ transform_matrix.x0, transform_matrix.y0);
+ graphene_matrix_multiply (&other, &matrix, &matrix);
+ graphene_matrix_init_translate (&other, &(graphene_point3d_t)GRAPHENE_POINT3D_INIT(- width / 2.0, - height / 2.0, 0));
+ graphene_matrix_multiply (&matrix, &other, &matrix);
+ gtk_snapshot_transform (snapshot, &matrix);
+
+ graphene_rect_init (&bounds, 0, 0, width, height);
+
+ node = gtk_snapshot_append (snapshot, &bounds, "Icon");
+ if (!_gtk_css_shadows_value_is_none (shadows))
+ {
+ g_warning ("Painting shadows not implemented for textures yet.");
+ }
+ gsk_render_node_set_texture (node, texture);
+ gsk_render_node_unref (node);
+
+ gtk_snapshot_set_transform (snapshot, &saved_matrix);
+}
#include <glib-object.h>
#include <cairo.h>
+#include <gsk/gsk.h>
#include "gtkcsstypesprivate.h"
+#include "gtksnapshot.h"
#include "gtktypes.h"
G_BEGIN_DECLS
cairo_surface_t *surface,
double x,
double y);
+void gtk_css_style_snapshot_icon (GtkCssStyle *style,
+ GtkSnapshot *snapshot,
+ GskTexture *texture);
void gtk_css_style_render_icon_get_extents (GtkCssStyle *style,
GdkRectangle *extents,
#include "gtkcssshadowsvalueprivate.h"
#include "gtkrenderbackgroundprivate.h"
#include "gtkrenderborderprivate.h"
+#include "gtkrendericonprivate.h"
#include "gtkstylecontextprivate.h"
#include "gsk/gskrendernodeprivate.h"
}
}
+GskRenderNode *
+gtk_snapshot_append (GtkSnapshot *state,
+ const graphene_rect_t *bounds,
+ const char *name,
+ ...)
+{
+ GskRenderNode *node;
+
+ g_return_val_if_fail (state != NULL, NULL);
+ g_return_val_if_fail (bounds != NULL, NULL);
+
+ node = gsk_renderer_create_render_node (state->renderer);
+ gsk_render_node_set_bounds (node, bounds);
+
+ if (name)
+ {
+ va_list args;
+ char *str;
+
+ va_start (args, name);
+ str = g_strdup_vprintf (name, args);
+ va_end (args);
+
+ gsk_render_node_set_name (node, str);
+
+ g_free (str);
+ }
+
+ gtk_snapshot_append_node (state, node);
+
+ return node;
+}
+
cairo_t *
gtk_snapshot_append_cairo_node (GtkSnapshot *state,
const graphene_rect_t *bounds,
gtk_snapshot_translate_2d (state, -x, -y);
}
+void
+gtk_snapshot_render_icon (GtkSnapshot *snapshot,
+ GtkStyleContext *context,
+ GdkPixbuf *pixbuf,
+ gdouble x,
+ gdouble y)
+{
+ GskTexture *texture;
+
+ texture = gsk_texture_new_for_pixbuf (snapshot->renderer, pixbuf);
+ gtk_snapshot_translate_2d (snapshot, x, y);
+ gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context),
+ snapshot,
+ texture);
+ gtk_snapshot_translate_2d (snapshot, -x, -y);
+ gsk_texture_unref (texture);
+}
+
void gtk_snapshot_append_node (GtkSnapshot *state,
GskRenderNode *node);
GDK_AVAILABLE_IN_3_90
+GskRenderNode * gtk_snapshot_append (GtkSnapshot *state,
+ const graphene_rect_t *bounds,
+ const char *name,
+ ...) G_GNUC_PRINTF(3, 4);
+GDK_AVAILABLE_IN_3_90
cairo_t * gtk_snapshot_append_cairo_node (GtkSnapshot *state,
const graphene_rect_t *bounds,
const char *name,
PangoLayout *layout,
int index,
PangoDirection direction);
+GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_render_icon (GtkSnapshot *snapshot,
+ GtkStyleContext *context,
+ GdkPixbuf *pixbuf,
+ gdouble x,
+ gdouble y);
G_END_DECLS